#pragma once

#include "DesktopCapturer.h"

class DesktopCapturerWin : public DesktopCapturer {
public:
	explicit DesktopCapturerWin(const DesktopCaptureOptions& options);
	~DesktopCapturerWin() override;

	// Overridden from ScreenCapturer:
	void Start(Callback* callback) override;
	void SetSharedMemoryFactory(
		std::unique_ptr<SharedMemoryFactory> shared_memory_factory) override;
	void CaptureFrame() override;
	bool GetSourceList(SourceList* sources) override;
	bool SelectSource(SourceId id) override;

private:
	typedef HRESULT(WINAPI* DwmEnableCompositionFunc)(UINT);

	// Make sure that the device contexts match the screen configuration.
	void PrepareCaptureResources();

	// Captures the current screen contents into the current buffer. Returns true
	// if succeeded.
	bool CaptureImage();

	// Capture the current cursor shape.
	void CaptureCursor();

	Callback* callback_ = nullptr;
	std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
	SourceId current_screen_id_ = kFullDesktopScreenId;
	std::wstring current_device_key_;

	ScopedThreadDesktop desktop_;

	// GDI resources used for screen capture.
	HDC desktop_dc_ = NULL;
	HDC memory_dc_ = NULL;

	// Queue of the frames buffers.
	DesktopCaptureFrameQueue<SharedDesktopFrame> queue_;

	DisplayConfigurationMonitor display_configuration_monitor_;

	HMODULE dwmapi_library_ = NULL;
	DwmEnableCompositionFunc composition_func_ = nullptr;

	DesktopCapturerWin(const DesktopCapturerWin&) = delete;
	DesktopCapturerWin& operator=(const DesktopCapturerWin&) = delete;
};

